﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Web;

namespace TST.SharePointObjects
{
    internal class SharePointGroupReferences : ObjectReferenceList
    {
        public SharePointGroupReferences(LicensingMode licensingMode)
            : base(licensingMode)
        {
        }

        public override ObjectReferenceType ObjectReferenceType
        {
            get { return ObjectReferenceType.Unknown; }
        }

        internal void AddSecurableObject(ISecurableObject securableObject, SiteObjectList objects, SPWeb web, SPSite site, SPWebApplication webApplication, Boolean objectIsFolder)
        {
            if (securableObject.HasUniqueRoleAssignments)
            {
                foreach (SPRoleAssignment assignment in securableObject.RoleAssignments)
                {
                    if (assignment.Member is SPGroup)
                    {
                        SPGroup group = (SPGroup)assignment.Member;
                        SiteObject siteObject = objects.GetItemById(group.ID.ToString());
                        if (siteObject != null && siteObject.Index)
                        {
                            if (Globals.MatchingScope(siteObject, webApplication, site, web))
                            {
                                string refId = Globals.GetReferenceId(siteObject, group);
                                String objectID = String.Empty;
                                String objectTitle = String.Empty;
                                String listTitle = String.Empty;
                                String listUrl = String.Empty;
                                String refUrl = String.Empty;
                                ObjectReferenceType refType = ObjectReferenceType.Unknown;
                                if (securableObject is SPWeb)
                                {
                                    refType = ObjectReferenceType.SharePointGroupWeb;
                                    SPWeb refWeb = (SPWeb)securableObject;
                                    objectID = refWeb.ID.ToString("B");
                                    objectTitle = refWeb.Title;
                                    listUrl = web.Url;
                                    refUrl = String.Format("{0}/_layouts/editprms.aspx?obj={1}%2CWEB&sel={2}", web.Url, HttpUtility.UrlEncode(web.Url), group.ID.ToString());
                                }
                                else if (securableObject is SPList)
                                {
                                    refType = ObjectReferenceType.SharePointGroupList;
                                    SPList list = (SPList)securableObject;
                                    objectID = list.ID.ToString("B");
                                    objectTitle = list.Title;
                                    listTitle = list.Title;
                                    listUrl = site.MakeFullUrl(list.DefaultViewUrl);
                                    if (list is SPDocumentLibrary)
                                    {
                                        refUrl = String.Format("{0}/_layouts/editprms.aspx?obj={1}%2CDOCLIB&sel={2}", web.Url, HttpUtility.UrlEncode(list.ID.ToString("B")), group.ID.ToString());
                                    }
                                    else
                                    {
                                        refUrl = String.Format("{0}/_layouts/editprms.aspx?obj={1}%2CLIST&sel={2}", web.Url, HttpUtility.UrlEncode(list.ID.ToString("B")), group.ID.ToString());
                                    }
                                }
                                else if (securableObject is SPListItem)
                                {
                                    if (objectIsFolder)
                                    {
                                        refType = ObjectReferenceType.SharePointGroupFolder;
                                        SPListItem folderItem = (SPListItem)securableObject;
                                        SPFolder folder = folderItem.Folder;
                                        objectID = folder.Name;
                                        objectTitle = folder.Name;
                                        listTitle = folderItem.ParentList.Title;
                                        listUrl = site.MakeFullUrl(folderItem.ParentList.DefaultViewUrl);
                                        if (folderItem.ParentList is SPDocumentLibrary)
                                        {
                                            refUrl = String.Format("{0}/_layouts/editprms.aspx?obj={1}%2C{2}%2CDOCLIBFOLDER&sel={3}", web.Url, HttpUtility.UrlEncode(folder.ParentListId.ToString("B")), folder.Item.ID, group.ID);
                                        }
                                        else
                                        {
                                            refUrl = String.Format("{0}/_layouts/editprms.aspx?obj={1}%2C{2}%2CFOLDER&sel={3}", web.Url, HttpUtility.UrlEncode(folder.ParentListId.ToString("B")), folder.Item.ID, group.ID);
                                        }
                                    }
                                    else
                                    {
                                        refType = ObjectReferenceType.SharePointGroupItem;
                                        SPListItem item = (SPListItem)securableObject;
                                        objectID = item.ID.ToString();
                                        listTitle = item.ParentList.Title;
                                        listUrl = site.MakeFullUrl(item.ParentList.DefaultViewUrl);
                                        if (item.ParentList is SPDocumentLibrary)
                                        {
                                            objectTitle = item.File.Name;
                                            refUrl = String.Format("{0}/_layouts/editprms.aspx?obj={1}%2C{2}%2CDOCUMENT&sel={3}", web.Url, HttpUtility.UrlEncode(item.ParentList.ID.ToString("B")), item.ID, group.ID);
                                        }
                                        else
                                        {
                                            if (!String.IsNullOrEmpty(item.Title))
                                            {
                                                objectTitle = item.Title;
                                            }
                                            else
                                            {
                                                objectTitle = String.Format("Item {0}", item.ID);
                                            }
                                            refUrl = String.Format("{0}/_layouts/editprms.aspx?obj={1}%2C{2}%2CLISTITEM&sel={3}", web.Url, HttpUtility.UrlEncode(item.ParentList.ID.ToString("B")), item.ID, group.ID);
                                        }
                                    }
                                }
                                ObjectReference newReference = new ObjectReference(objectID, objectTitle, refId, refType);
                                newReference.Url = refUrl;
                                newReference.SiteTitle = web.Title;
                                newReference.SiteUrl = web.Url;
                                newReference.ListTitle = listTitle;
                                newReference.ListUrl = listUrl;
                                Add(newReference);
                            }
                        }
                    }
                }
            }
            if (securableObject is SPList)
            {
                foreach (SPFolder folder in ((SPList)securableObject).RootFolder.SubFolders)
                {
                    if (folder.Item != null)
                    {
                        AddSecurableObject(folder.Item, objects, web, site, webApplication, true);
                    }
                }
            }
            else if (securableObject is SPListItem && objectIsFolder)
            {
                SPListItem folderItem = (SPListItem)securableObject;
                SPFolder folder = folderItem.Folder;
                foreach (SPFolder subFolder in folder.SubFolders)
                {
                    if (subFolder.Item != null)
                    {
                        AddSecurableObject(subFolder.Item, objects, web, site, webApplication, true);
                    }
                }
            }
        }

        internal void Add(SPList list, SiteObjectList objects, SPWeb web, SPSite site, SPWebApplication webApplication)
        {
            AddSecurableObject(list, objects, web, site, webApplication, false);
            foreach (SPListItem item in list.Items)
            {
                AddSecurableObject(item, objects, web, site, webApplication, false);
            }
        }

    }
}
